package com.hzw.saas.service.chat.service;


import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzw.saas.api.chat.IChatEventService;
import com.hzw.saas.api.chat.IChatGroupService;
import com.hzw.saas.api.chat.IChatUserGroupService;
import com.hzw.saas.api.chat.bo.ChatEventBO;
import com.hzw.saas.api.chat.bo.ChatGroupBO;
import com.hzw.saas.api.chat.bo.ChatUserGroupBO;
import com.hzw.saas.api.chat.bo.SingleGroupBO;
import com.hzw.saas.api.group.IGroupMemberService;
import com.hzw.saas.api.group.IGroupService;
import com.hzw.saas.api.group.bo.GroupBo;
import com.hzw.saas.api.group.event.GroupCreateEvent;
import com.hzw.saas.common.config.util.AssertUtil;
import com.hzw.saas.common.util.MapperUtil;
import com.hzw.saas.common.util.SnowFlakeUtil;
import com.hzw.saas.service.chat.mapper.ChatGroupMapper;
import com.hzw.saas.service.chat.model.ChatGroup;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.net.InetAddress;
import java.util.*;
import java.util.stream.Collectors;

;


@Service("chatGroupService")
public class ChatGroupServiceImpl extends ServiceImpl<ChatGroupMapper, ChatGroup> implements IChatGroupService, IService<ChatGroup> {
    @Resource(name = "chatEventService")
    private IChatEventService chatEventService;

    @Resource(name = "groupServiceImpl")
    private IGroupService groupService;

    @Resource(name = "groupMemberServiceImpl")
    private IGroupMemberService groupMemberService;

    @Resource(name = "chatUserGroupService")
    private IChatUserGroupService chatUserGroupService;
    @Override
    public void addGroup(String userId, List<SingleGroupBO> singleGroupBOS, Integer groupType) {
            //新增群组
            if (CollectionUtil.isNotEmpty(singleGroupBOS)){
                ArrayList<ChatGroup> chatGroups = new ArrayList<>();
                singleGroupBOS.forEach(singleGroupBO -> {
                    ChatGroup chatGroup = new ChatGroup();
                    chatGroup.setGroupName(singleGroupBO.getGroupName());
                    chatGroup.setPid(singleGroupBO.getGroupId());
                    chatGroup.setCreatorId(userId);
                    chatGroup.setCreateTime(new Date());
                    chatGroups.add(chatGroup);
                });
                this.saveBatch(chatGroups);
                changeGroupEvent(chatGroups,21,userId);
            }
    }


    private void changeGroupEvent(List<ChatGroup> chatGroups,Integer type,String userId){
        if (CollectionUtil.isNotEmpty(chatGroups)){
            ArrayList<ChatEventBO> chatEventBOS = new ArrayList<>();
            chatGroups.forEach(chatGroup -> {
                ChatEventBO chatEventBO = new ChatEventBO();
                chatEventBO.setPid(SnowFlakeUtil.nextIdStr());
                chatEventBO.setEventType(type);
                chatEventBO.setSourceId(userId);
                chatEventBO.setGroupType(2);
                chatEventBO.setTargetGroupId(chatGroup.getPid());
                chatEventBOS.add(chatEventBO);
            });
            chatEventService.saveBatch(chatEventBOS);
        }

    }

    @Override
    public List<ChatGroupBO> findByIds(List<String> groupIds) {
        if (CollectionUtil.isEmpty(groupIds)){
            return Collections.emptyList();
        }
        List<ChatGroup> list = this.lambdaQuery().in(ChatGroup::getPid, groupIds).list();
        return MapperUtil.nf().mapAsList(list,ChatGroupBO.class);
    }

    @Override
    public ChatGroupBO findFriendGroup(String userId, String friendId) {
        return null;
    }

    @Override
    public void deleteFriend(String userId, String friendId) {

    }

    @Override
    public List<ChatGroupBO> findNeedStatusGroup(List<String> groupIds, List<Integer> status, List<Integer> groupType) {
        return null;
    }

    @Override
    public void deleteGroup(String userId, String groupId) {
        AssertUtil.assertThrow("用户权限不足",!hasGroupPermission(userId,groupId));
        List<ChatGroup> list = this.lambdaQuery().eq(ChatGroup::getPid, groupId).list();
        if (CollectionUtil.isEmpty(list)){
            return;
        }
        ChatGroup chatGroup = list.get(0);
        //群组删除事件,类型id 23
        changeGroupEvent(list,23,userId);
        //删除群组
        this.removeById(chatGroup.getPid());
        //批量踢出群组事件
        List<ChatUserGroupBO> usersByGroupId = chatUserGroupService.findUsersByGroupId(chatGroup.getPid());
        if (CollectionUtil.isNotEmpty(usersByGroupId)){
            ArrayList<ChatEventBO> chatEventBOS = new ArrayList<>();
            usersByGroupId.forEach(chatUserGroupBO -> {
                ChatEventBO chatEventBO = new ChatEventBO();
                chatEventBO.setGroupType(chatUserGroupBO.getGroupType());
                chatEventBO.setEventDetail("group delete，removed");
                chatEventBO.setSourceId(userId);
                chatEventBO.setTargetUserId(chatUserGroupBO.getUserId());
                chatEventBO.setEventType(28);
                chatEventBO.setTargetGroupId(chatUserGroupBO.getGroupId());
                chatEventBOS.add(chatEventBO);
            });
            chatEventService.saveBatch(chatEventBOS);
        }

        //删除群组的关联信息
        chatUserGroupService.deleteByGroupId(chatGroup.getPid());


    }

    @Override
    public void updateGroup(String userId, String groupId, String groupName) {
        AssertUtil.assertThrow("用户权限不足",!hasGroupPermission(userId,groupId));
        List<ChatGroup> list = this.lambdaQuery().eq(ChatGroup::getPid, groupId).list();
        ChatGroup chatGroup = list.get(0);
        chatGroup.setGroupName(groupName);
        changeGroupEvent(list,22,userId);
        this.updateById(chatGroup);
    }


    /**
     * 根据用户id和群组id查询用户是否拥有该群组的权限
     * @param userId
     * @param groupId
     * @return
     */
    private boolean hasGroupPermission(String userId,String groupId){
        List<ChatGroup> list = this.lambdaQuery().eq(ChatGroup::getPid, groupId)
            .list();
        if (CollectionUtil.isEmpty(list)){
            return false;
        }
        ChatGroup chatGroup = list.get(0);
        if (chatGroup.getCreatorId() != null && chatGroup.getCreatorId().equals(userId)){
            return true;
        }
        return false;
    }

    @Override
    @Transactional
    public void  initData(){
        List<ChatGroup> list = this.lambdaQuery().eq(ChatGroup::getPid, "0000").list();
        if (CollectionUtil.isNotEmpty(list)){
            return;
        }
        //生成初始化数据
        ChatGroup chatGroup1 = new ChatGroup();
        chatGroup1.setPid("0000");
        chatGroup1.setGroupName("洪之微");
        chatGroup1.setCreatorId("0000");
        chatGroup1.setEditorId("0000");
        this.save(chatGroup1);

        List<GroupBo> needRefresh = groupService.findNeedRefresh();
        if (CollectionUtil.isNotEmpty(needRefresh)){
            ArrayList<ChatGroup> chatGroupS = new ArrayList<>();
            needRefresh.forEach(groupBo -> {
                ChatGroup chatGroup = new ChatGroup();
                chatGroup.setGroupName(groupBo.getGroupName());
                chatGroup.setPid(groupBo.getGroupId());
                chatGroupS.add(chatGroup);
            });
            //批量新增群组
            this.saveBatch(chatGroupS);
            //新增群组事件
            ArrayList<ChatEventBO> chatEventBOS = new ArrayList<>();
            needRefresh.forEach(groupBo -> {
                ChatEventBO chatEventBO = new ChatEventBO();
                chatEventBO.setEventDetail(groupBo.getOwnerId() + "crete:" +groupBo.getGroupName());
                chatEventBO.setGroupType(2);
                chatEventBO.setSourceId(groupBo.getOwnerId());
                chatEventBO.setTargetGroupId(groupBo.getGroupId());
                chatEventBO.setEventType(21);
                chatEventBOS.add(chatEventBO);
            });
            //新增事件
            chatEventService.saveBatch(chatEventBOS);
            //查出所有的群的群成员
            List<String> groupIds = needRefresh.stream().map(GroupBo::getGroupId).collect(Collectors.toList());
            Map<String, List<String>> allByIds = groupMemberService.getAllByIds(groupIds);
            ArrayList<ChatUserGroupBO> chatUserGroupBOS = new ArrayList<>();
            allByIds.forEach((s, stringList) -> {
                stringList.forEach(s1 -> {
                    ChatUserGroupBO chatUserGroupBO = new ChatUserGroupBO();
                    chatUserGroupBO.setGroupId(s);
                    chatUserGroupBO.setUserId(s1);
                    chatUserGroupBO.setPermission(1);
                    chatUserGroupBOS.add(chatUserGroupBO);
                });
            });
            chatUserGroupService.saveBatch(chatUserGroupBOS);
            //新人加群事件
            ArrayList<ChatEventBO> eventBOS = new ArrayList<>();
            chatUserGroupBOS.forEach(chatUserGroupBO -> {
                ChatEventBO chatEventBO = new ChatEventBO();
                chatEventBO.setEventType(25);
                chatEventBO.setSourceId(chatUserGroupBO.getUserId());
                chatEventBO.setEventDetail(chatUserGroupBO.getUserId()+"join:"+chatUserGroupBO.getGroupId());
                chatEventBO.setTargetUserId(chatUserGroupBO.getUserId());
                chatEventBO.setGroupType(2);
                eventBOS.add(chatEventBO);
            });
            chatEventService.saveBatch(eventBOS);
            chatEventService.makeSource();
        }
    }

}
